<?php
// 引入TP8核心文件
require __DIR__ . '/../vendor/autoload.php';
define('APP_PATH', __DIR__ . '/../application/');

use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
use think\App;
use think\exception\Handle;
use think\facade\Config;

// 优化：直接使用TP8的HTTP响应处理，避免手动拼接
class HttpKernel
{
    protected $app;

    public function __construct(App $app)
    {
        $this->app = $app;
    }

    public function handle(TcpConnection $connection, $request)
    {
        try {
            // 设置请求处理超时（单位：秒）
            $connection->maxSendBufferSize = 1024*1024*5; // 5MB
            $connection->maxPackageSize = 1024*1024*5;   // 5MB

            // 设置超时计时器（120秒后自动关闭连接）
//            $connection->timeoutTimer = Timer::add(120, function() use ($connection){
//                $connection->close();
//            });
            // 转换请求（优化版）
            $tpRequest = $this->app->request
                ->setMethod($request->method())
                ->setUrl($request->uri())
                ->withGet($request->get())
                ->withPost($request->post())
                ->withHeader($request->header())
                ->withServer([
                    'REQUEST_URI' => $request->uri(),
                    'REQUEST_METHOD' => $request->method(),
                    'REMOTE_ADDR' => $connection->getRemoteIp(),
                    'SERVER_PROTOCOL' => 'HTTP/1.1',
                    'HTTP_HOST' => $request->host(),
                    'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'] ?? '',
                    'SCRIPT_NAME' => '',
                    'PHP_SELF' => '',
                ]);

            // 注入请求并执行（关键优化：使用TP8原生流程）
            $this->app->request = $tpRequest;
            $response = $this->app->http->run();

            // 直接使用TP8的响应发送（避免手动拼接，效率更高）
            $responseContent = $response->getContent();
            $statusCode = $response->getCode();
            $headers = $response->getHeader();

            // 构建响应头（TP8已处理，直接获取）
//            $httpResponse = "HTTP/1.1 {$statusCode} " . $this->getStatusReason($statusCode) . "\r\n";
//            foreach ($headers as $name => $values) {
//                $httpResponse .= "{$name}: {$values[0]}\r\n";
//            }
//            $httpResponse .= "Content-Length: " . strlen($responseContent) . "\r\n\r\n{$responseContent}";
            // 构建响应头（TP8已处理，直接获取）
            $httpResponse = "HTTP/1.1 {$statusCode} " . $this->getStatusReason($statusCode) . "\r\n";

            // 强制设置JSON响应头并移除重复头
            $headers = array_change_key_case($response->getHeader(), CASE_LOWER);
            unset($headers['content-type']);

            foreach ($headers as $name => $values) {
                $httpResponse .= "{$name}: {$values[0]}\r\n";
            }
            $httpResponse .= "Content-Type: application/json\r\n";

            // 确保内容为JSON格式
            $responseContent = json_encode(json_decode($response->getContent()), JSON_UNESCAPED_UNICODE);
            $httpResponse .= "Content-Length: " . strlen($responseContent) . "\r\n\r\n";
            $httpResponse .= $responseContent;
            $connection->send($responseContent);
            // 处理完成后清除计时器
//            Timer::del($connection->timeoutTimer);
        } catch (\Exception $e) {
            $this->handleException($connection, $e);
        }
    }

    // 获取状态原因（优化版）
    protected function getStatusReason($code)
    {
        $map = [
            200 => 'OK', 201 => 'Created', 204 => 'No Content',
            400 => 'Bad Request', 401 => 'Unauthorized', 403 => 'Forbidden',
            404 => 'Not Found', 405 => 'Method Not Allowed',
            500 => 'Internal Server Error', 502 => 'Bad Gateway', 503 => 'Service Unavailable',
        ];
        return $map[$code] ?? 'OK';
    }

    // 异常处理（统一格式）
    protected function handleException(TcpConnection $connection, \Exception $e)
    {
        $data = [
            'code' => 500,
            'msg' => $e->getMessage(),
            'file' => $e->getFile(),
            'line' => $e->getLine(),
        ];
        $response = "HTTP/1.1 500 Internal Server Error\r\n";
        $response .= "Content-Type: application/json\r\n";
        $response .= "Content-Length: " . strlen(json_encode($data)) . "\r\n\r\n";
        $response .= json_encode($data);
        $connection->send($response);
    }
}

// 创建HTTP服务
$http = new Worker('http://0.0.0.0:8081');
$http->count = 16; // 根据CPU核心数设置（建议为CPU核心数的2倍）
// 正确设置连接空闲超时（单位：秒）
//TcpConnection::$idleTimeout = 120;

// 设置心跳检测（替代空闲超时）
//$http->onWorkerStart = function($worker) {
//    Timer::add(55, function() use ($worker){
//        foreach($worker->connections as $connection) {
//            if (time() - $connection->lastMessageTime > 120) {
//                $connection->close();
//            }
//        }
//    });
//};
// 初始化TP应用（优化：每次请求重新实例化，避免状态污染）
$http->onMessage = function (TcpConnection $connection, $request) {
    $app = new App();
    $app->setAppPath(APP_PATH);
    $app->initialize();

    // 加载配置（确保TP功能正常）
    $app->config->load($app->getConfigPath());

    // 处理请求
    $kernel = new HttpKernel($app);
    $kernel->handle($connection, $request);
};

// 启动服务
Worker::runAll();